﻿using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using Mido.Properties;
using Mido.UiModules.AboutDialogModule;
using Mido.UiModules.ActiveImageModule;
using Mido.UiModules.SaveDialogModule;
using Mido.UiModules.ScrollBarModule;
using Mido.UiModules.SettingsModule;
using Mido.Utils.Mvvm;
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Windows.Forms;
using Application = System.Windows.Application;
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;

namespace Mido.Domain
{
    public class DomainViewModel : ViewModelBase
    {
        private readonly DomainModel _model;

		private readonly ActiveImageViewModel _activeImageViewModel;
	    private readonly ScrollBarViewModel _scrollBarViewModel;
	    private readonly SettingsViewModel _settingsViewModel;
	    private readonly SaveDialogModel _saveDialogModel;

	    private bool _hasAnyImages;

        internal DomainViewModel(DomainModel model)
        {
            if (model == null) 
                throw new ArgumentNullException("model");

            _model = model;
			_model.Images.CollectionChanged += OnImagesCollectionChanged;

			_activeImageViewModel = new ActiveImageViewModel(_model.ActiveImageModel);
			_scrollBarViewModel = new ScrollBarViewModel(_model.ScrollBarModel);
	        _settingsViewModel = new SettingsViewModel(_model.Settings);
			_saveDialogModel = new SaveDialogModel(_model);
        }

		private void OnImagesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
		{
			if (_hasAnyImages == _model.Images.Any())
				return;

			_hasAnyImages = _model.Images.Any();

			RaisePropertyChanged("ShowImageViewers");
			RaisePropertyChanged("ShowDeveloperText");
		}

	    public Visibility ShowImageViewers
	    {
			get { return _hasAnyImages ? Visibility.Visible : Visibility.Hidden; }
	    }

	    public string Localization
	    {
			get { return _model.Localization; }
			set { _model.Localization = value; }
	    }

		public IEnumerable<Tuple<string, string>> AvailableLocalizations
	    {
			get
			{
				return new[]
				{
					new Tuple<string, string>(Resources.DomainViewModel_AvailableLocalizations_Default_language, string.Empty), 
				    new Tuple<string, string>("English", "en-US"), 
				    new Tuple<string, string>("Русский", "ru-RU")
				};
			}
	    }

		public Visibility ShowDeveloperText
	    {
			get { return _hasAnyImages ? Visibility.Collapsed : Visibility.Visible; }
	    }
		
        public SettingsViewModel SettingsViewModel
        {
			get { return _settingsViewModel; }
        }

        public ScrollBarViewModel ScrollBarViewModel
        {
			get { return _scrollBarViewModel; }
        }

        public ActiveImageViewModel ActiveImageViewModel
        {
            get { return _activeImageViewModel; }
        }

	    public SaveDialogModel SaveDialogModel
	    {
			get { return _saveDialogModel; }
	    }

        public SimpleCommand ShowHideSettingsCommand
        {
            get { return new SimpleCommand(OnShowHideSettings); }
        }

        public SimpleCommand OpenImageCommand
        {
            get { return new SimpleCommand(OnOpenImage); }
        }

        public SimpleCommand OpenFolderCommand
        {
            get { return new SimpleCommand(OnOpenFolder); }
        }

        public SimpleCommand SaveCommand
        {
            get { return new SimpleCommand(OnSave); }
        }

		public SimpleCommand AboutCommand
		{
			get { return new SimpleCommand(OnAbout); }
		}

		public SimpleCommand FeedbackCommand
		{
			get { return new SimpleCommand(OnFeedback); }
		}

	    private void OnFeedback()
	    {
			Process.Start("http://mido.codeplex.com/");
	    }

	    private void OnAbout()
	    {
		    AboutWindow window = new AboutWindow { Owner = App.Current.MainWindow };
		    window.ShowDialog();
	    }

	    private void OnSave()
        {
			SaveDialogWindow saveDialogWindow = new SaveDialogWindow { Owner = App.Current.MainWindow };
		    saveDialogWindow.DataContext = new SaveDialogViewModel(SaveDialogModel);
		    saveDialogWindow.ShowDialog();
        }

        private void OnOpenFolder()
        {
            FolderBrowserDialog dialog = new FolderBrowserDialog();
            DialogResult result = dialog.ShowDialog();

            if (result != DialogResult.OK)
                return;
	        
			_saveDialogModel.DestinitionFolder = dialog.SelectedPath;

			List<string> images = new List<string>();
			images.AddRange(Directory.GetFileSystemEntries(dialog.SelectedPath, "*.bmp"));
            images.AddRange(Directory.GetFileSystemEntries(dialog.SelectedPath, "*.jpg"));
			images.AddRange(Directory.GetFileSystemEntries(dialog.SelectedPath, "*.jpeg"));
			images.AddRange(Directory.GetFileSystemEntries(dialog.SelectedPath, "*.png"));
			
			_scrollBarViewModel.SetProgressBar(true, 0);

			BackgroundWorker worker = new BackgroundWorker();
	        worker.DoWork += (sender, e) =>
			{
				ProcessedImage[] items = new ProcessedImage[images.Count];

				_hasAnyImages = true;
				RaisePropertyChanged("ShowImageViewers");
				RaisePropertyChanged("ShowDeveloperText");

				for (int index = 0; index < images.Count; index++)
				{
					ProcessedImage image = new ProcessedImage(images[index], _model.Settings);
					items[index] = image;
//					_model.AddImage(image);

					_scrollBarViewModel.SetProgressBar(true, (index + 1) / Convert.ToDouble(images.Count) * 100D);
				}

				e.Result = items;
			};

	        worker.RunWorkerCompleted += (sender, e) =>
			{
				ProcessedImage[] items = (ProcessedImage[])e.Result;
				for (int index = 0; index < items.Length; index++)
				{
					_model.AddImage(items[index]);
				}

				_scrollBarViewModel.SetProgressBar(false, 0);
				_model.SelectImage(_model.Images.Count - 1);
			};

			worker.RunWorkerAsync();
		}

        private void OnOpenImage()
        {
            OpenFileDialog dialog = new OpenFileDialog();
			dialog.Filter = "Image Files(*.BMP;*.JPG;*.JPEG;*.PNG)|*.BMP;*.JPG;*.JPEG;*.PNG|All files (*.*)|*.*";
            bool? result = dialog.ShowDialog(Application.Current.MainWindow);

            if (!result.Value)
                return;

	        _saveDialogModel.DestinitionFolder = Path.GetDirectoryName(dialog.FileName);

            ProcessedImage image = new ProcessedImage(dialog.FileName, _model.Settings);

			_model.AddImage(image);   
            _model.SelectImage(_model.Images.Count - 1);
        }

        public Visibility PanelVisibility
        {
            get { return _settingsViewModel.IsSettingsShown ? Visibility.Visible : Visibility.Collapsed; }
        }

	    private void OnShowHideSettings()
        {
            _settingsViewModel.IsSettingsShown = !_settingsViewModel.IsSettingsShown;
            RaisePropertyChanged("PanelVisibility");
        }
    }
}
